#!/usr/bin/env python
# -*- coding: utf-8 -*-

# from utils.log import logger
from module_interfaces import PARAM
from utils.memory import get_meminfo
import re


class memsize(PARAM):
    """
    memsize
        50%total
        50%free
        50%avail
        50%total+swap
    """

    field_map = {
        'total': 'MemTotal',
        'free': 'MemFree',
        'avail': 'MemAvailable',
        'swap': 'SwapTotal',
    }

    def _extract_ratio(self, value):
        reg = re.compile(r'^(\d+)%(\D+)$')
        result = reg.search(value)
        ratio = 1.0
        if result:
            ratio = float(result.groups()[0]) / 100.0
            field = result.groups()[1]
        else:
            reg = re.compile(r'^(\d+)%')
            result = reg.search(value)
            if result:
                ratio = float(result.groups()[0]) / 100.0
                field = 'total'
            else:
                field = value
        return (ratio, field)

    def _create_op(self, field, operation):
        (ratio, field) = self._extract_ratio(field)
        if operation == '-':
            op = -1
        else:
            op = 1
        recorder = {
            'field': field,
            'op': op,
            'ratio': ratio,
        }
        return recorder

    def _parse_value(self, memtypes):
        memops = []
        memtype = ""
        pre_op = '+'
        for i in range(len(memtypes)):
            if memtypes[i] == '+':
                recorder = self._create_op(memtype, pre_op)
                memops.append(recorder)
                memtype = ""
                pre_op = '+'
            elif memtypes[i] == '-':
                recorder = self._create_op(memtype, pre_op)
                memops.append(recorder)
                memtype = ""
                pre_op = '-'
            else:
                memtype += memtypes[i]
        recorder = self._create_op(memtype, pre_op)
        memops.append(recorder)
        return memops

    def _to_bytes(self, value, unit):
        unit = unit.lower()
        movesize = {
            'b': 0,
            '': 0,
            'k': 10,
            'kb': 10,
            'm': 20,
            'mb': 20,
            'g': 30,
            'gb': 30,
            't': 40,
            'tb': 40,
            'p': 50,
            'pb': 50,
        }
        return value << movesize[unit]

    def get(self, value):
        # import pdb
        # pdb.set_trace()
        reg = re.compile(r'total|free|avail|swap|%')
        if reg.search(value):
            meminfo = get_meminfo()
            operator_info = self._parse_value(value)
            # print operator_info
            size = 0
            for op in operator_info:
                field = self.field_map[op['field']]
                size += self._to_bytes(
                    meminfo[field]['value'],
                    meminfo[field]['unit']) * op['op'] \
                    * op['ratio']
            if size < 0:
                size = 0
        else:
            reg = re.compile(r'(\d+)(\D*)')
            result = reg.search(value)
            if result:
                size = self._to_bytes(
                    int(result.groups()[0]),
                    result.groups()[1])
            else:
                size = 0
        return int(size)
